package com.lanhai.zhonglai.impl;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.google.gson.Gson;
import com.lanhai.zhonglai.beans.StationBean;
import com.lanhai.zhonglai.beans.StationBlackBean;
import com.lanhai.zhonglai.beans.StationLockBean;
import com.lanhai.zhonglai.beans.StationMountBean;
import com.lanhai.zhonglai.dao.StationDao;
import com.lanhai.zhonglai.dao.StationGroupDao;
import com.lanhai.zhonglai.enums.CacheStationEnumType;
import com.lanhai.zhonglai.enums.TransDirectionEnum;
import com.lanhai.zhonglai.hc.HCQueue;
import com.lanhai.zhonglai.interfaces.ISendData;
import com.lanhai.zhonglai.interfaces.IStation;
import com.lanhai.zhonglai.interfaces.IStationMount;
import com.lanhai.zhonglai.interfaces.IStationProtocol;
import com.lanhai.zhonglai.mapper.StationMapper;
import com.lanhai.zhonglai.third.StationFactory;
import com.lanhai.zhonglai.utils.StationTeamUtils;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

@Service
public class StationImpl implements IStation {

    @Autowired
    ISendData sendTools;

    @Autowired
    StationMapper stationMapper;

    @Autowired
    IStationMount stationMount;

    @Autowired
    StationTeamUtils teamUtils;

    @Autowired
    JedisPool jedisPool;
    Gson gson = new Gson();

    // IP：设备
    static Map<String, StationBean> ipMap = new ConcurrentHashMap<String, StationBean>();

    // IP:指令
    static Map<String, String> cmdMap = new ConcurrentHashMap<String, String>();

    // 所有的机台列表
    static Map<Integer, StationDao> stationList = new ConcurrentHashMap<Integer, StationDao>();

    // 机台的上锁解锁列表
    static Map<Integer, StationLockBean> lockList = new ConcurrentHashMap<Integer, StationLockBean>();


    // 分配目标机台的黑名单，点位：列表
    // 在列表里面的就不用分配（只读不分配）
    static Map<Integer, StationBlackBean> blackList = new HashMap<Integer, StationBlackBean>();


    @Override
    public void init() {

        /*
         * 不能做分配的名单，禁止左边的点去右边 左边是判断的机台工位（注意，是机台） 右边的列表为不分配的机台工位
         *
         */
        if (blackList.size() == 0) {
            // 扩散
            blackList.put(22, new StationBlackBean(22, new int[]{20}));
            blackList.put(28, new StationBlackBean(28, new int[]{20, 24, 26}));
            blackList.put(30, new StationBlackBean(30, new int[]{20, 24, 26, 28}));
            blackList.put(36, new StationBlackBean(36, new int[]{20, 24, 26, 28, 32, 34}));
            blackList.put(38, new StationBlackBean(38, new int[]{20, 24, 26, 28, 32, 34}));

            //制绒下料缓存机
            blackList.put(254, new StationBlackBean(254, new int[]{18, 20, 22, 24}));

            //扩散下料缓存机
            blackList.put(256, new StationBlackBean(256, new int[]{18, 20, 22, 24, 26, 28, 30, 32}));

            // 退火
            blackList.put(94, new StationBlackBean(94, new int[]{92}));
            blackList.put(98, new StationBlackBean(98, new int[]{92, 96}));
            blackList.put(102, new StationBlackBean(102, new int[]{92, 96, 100}));

            // popaid
            blackList.put(44, new StationBlackBean(44, new int[]{42}));
            blackList.put(46, new StationBlackBean(46, new int[]{42, 44}));
            blackList.put(48, new StationBlackBean(48, new int[]{42, 44, 46}));

            // 正膜
            blackList.put(128, new StationBlackBean(128, new int[]{124, 126}));
            blackList.put(130, new StationBlackBean(130, new int[]{124, 126}));
            blackList.put(136, new StationBlackBean(136, new int[]{124, 126, 132, 134}));
            blackList.put(138, new StationBlackBean(138, new int[]{124, 126, 132, 134}));
            blackList.put(144, new StationBlackBean(144, new int[]{124, 126, 132, 134, 140, 142}));
            blackList.put(146, new StationBlackBean(146, new int[]{124, 126, 132, 134, 140, 142}));

            // 背膜
            blackList.put(152, new StationBlackBean(152, new int[]{150}));
            blackList.put(154, new StationBlackBean(154, new int[]{150}));
            blackList.put(160, new StationBlackBean(160, new int[]{150, 156, 158}));
            blackList.put(120, new StationBlackBean(120, new int[]{150, 156, 158}));
            blackList.put(114, new StationBlackBean(114, new int[]{150, 156, 158, 118, 116}));
            blackList.put(112, new StationBlackBean(112, new int[]{150, 156, 158, 118, 116}));
            blackList.put(106, new StationBlackBean(106, new int[]{150, 156, 158, 118, 116, 110, 108}));

        }


        teamUtils.init();

        List<StationDao> tmp = stationMapper.getStationList();
        stationList.clear();
        if (tmp != null) {
            for (StationDao dao : tmp) {
                StationBean bean = transDaoToBean(dao);
                stationList.put(dao.getDotno(), dao);

                String key = String.format("%s_%d", bean.getIp(), bean.getLine());
                ipMap.put(key, bean);
                cmdMap.put(bean.getIp(), bean.getCmdSign());
            }
        }

        lockList.clear();
        if (tmp != null) {
            String key = "stationlocklist";
            Jedis jd = jedisPool.getResource();
            Map<String, String> rmap = jd.hgetAll(key);
            jd.close();

            for (StationDao dao : tmp) {
                StationLockBean obj = new StationLockBean();
                obj.setDotno(dao.getDotno());
                obj.setProcess(dao.getProcess());


                String json = rmap.get(dao.getDotno() + "");
                if (json != null) {
                    try {
                        StationLockBean x = gson.fromJson(json, StationLockBean.class);
                        obj.setAgvid(x.getAgvid());
                        obj.setIslock(x.isIslock());
                        obj.setLasttime(x.getLasttime());
                        if (x.isIslock()) {
                            teamUtils.setLock(x.getDotno(), true);
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
                lockList.put(obj.getDotno(), obj);
            }
        }

        //teamUtils.setLock(208, true);
    }

    /**
     * 先缓存后mysql。此方法拿到的对象不用于传输判断
     */
    @Override
    public synchronized StationBean getBeanByIP(String ip, int line) {
        String key = String.format("%s_%d", ip, line);
        StationBean bean = ipMap.get(key);
        return bean;
    }

    /**
     * 从点位拿机台， 从db中获取实时数据，涉及到传输
     */
    @Override
    public StationBean getBeanByDot(int dotno) {

        StationDao dao = stationList.get(dotno);
        if (dao != null) {
            return transDaoToBean(dao);
        } else {
            return null;
        }
    }

    @Override
    public synchronized String getCmdSign(String ip) {
        String cmd = cmdMap.get(ip);
        return cmd;
    }

    /**
     * 点位释放
     */
    @Override
    public void unlockStationForDot(int dotno, int agvId) {
        StationLockBean dao = lockList.get(dotno);
        if (dao != null) {
            if (dao.getAgvid() == agvId) {
                dao.setAgvid(0);
                dao.setIslock(false);
                teamUtils.setLock(dotno, false);

                saveToRedis(dao);

            }
        }
    }


    @Override
    public synchronized void unlockStationByHacker(int dotno) {
        StationLockBean dao = lockList.get(dotno);
        if (dao != null) {
            dao.setAgvid(0);
            dao.setIslock(false);
            dao.setLasttime(System.currentTimeMillis());
            teamUtils.setLock(dotno, false);
            saveToRedis(dao);
        }

    }


    /**
     * 某工序分组下不分线别的未锁定的机台
     *
     * @param processgroup
     * @return
     */
    synchronized List<StationGroupDao> getEmptyListNoSpecialLine(int dotno, String process, int agvid) {
        List<StationGroupDao> re = new ArrayList<StationGroupDao>();
        StationBlackBean black = blackList.get(dotno);
        for (Entry<Integer, StationDao> entry : stationList.entrySet()) {
            StationDao tmp = entry.getValue();

            if (tmp.getProcess().equals(process) == false) {
                continue;
            }

            if (tmp.isIsdisable()) {
                continue;
            }

            // 分组的过滤掉
            if (teamUtils.canUse(tmp.getDotno(), agvid) == false) {
                continue;
            }

            // 不能分配的过滤掉
            if (black != null && black.inList(tmp.getDotno())) {
                continue;
            }

            StationLockBean p = lockList.get(tmp.getDotno());
            if (p != null && (p.isIslock() == false || p.getAgvid() == agvid)) {
                StationGroupDao obj = new StationGroupDao();
                obj.setStationname(tmp.getStationname());
                obj.setDotno(tmp.getDotno());
                obj.setLasttime(p.getLasttime());
                obj.setTransnum(tmp.getTransnum());
                obj.setLeastnum(tmp.getLeastnum());
                obj.setDleastnum(tmp.getDleastnum());
                obj.setProcess(tmp.getProcess());
                obj.setSpecialline(tmp.getSpecialline());
                re.add(obj);

            }
        }
        return re;
    }

    synchronized List<StationGroupDao> getEmptyListNoSpecialLineDot(int dotno, List<Integer> dotList, int agvid) {
        List<StationGroupDao> re = new ArrayList<StationGroupDao>();
        StationBlackBean black = blackList.get(dotno);
        for (Entry<Integer, StationDao> entry : stationList.entrySet()) {
            StationDao tmp = entry.getValue();

            if (dotList.contains(tmp.getDotno()) == false) {
                continue;
            }

            if (tmp.isIsdisable()) {
                continue;
            }

            // 分组的过滤掉
            if (teamUtils.canUse(tmp.getDotno(), agvid) == false) {
                continue;
            }

            // 不能分配的过滤掉
            if (black != null && black.inList(tmp.getDotno())) {
                continue;
            }

            StationLockBean p = lockList.get(tmp.getDotno());
            if (p != null && (p.isIslock() == false || p.getAgvid() == agvid)) {
                StationGroupDao obj = new StationGroupDao();
                obj.setStationname(tmp.getStationname());
                obj.setDotno(tmp.getDotno());
                obj.setLasttime(p.getLasttime());
                obj.setTransnum(tmp.getTransnum());
                obj.setLeastnum(tmp.getLeastnum());
                obj.setDleastnum(tmp.getDleastnum());
                obj.setProcess(tmp.getProcess());
                obj.setSpecialline(tmp.getSpecialline());
                re.add(obj);

            }
        }
        return re;
    }

    /**
     * 弃用
     *
     * @param agvid
     * @return
     */
    synchronized List<StationGroupDao> getEmptyListForZRS(int agvid) {
        List<StationGroupDao> re = new ArrayList<StationGroupDao>();

        List<Integer> arr = Arrays.asList(2, 4, 6, 8, 204, 206, 208, 210, 212, 214, 216, 218);
        Map<Integer, Integer> map = new HashMap<Integer, Integer>();
        for (Entry<Integer, StationDao> entry : stationList.entrySet()) {
            StationDao tmp = entry.getValue();
            if (tmp.isIsdisable()) {
                continue;
            }
            if (arr.contains(tmp.getDotno())) {
                //先把没锁的弄进来

                StationLockBean p = lockList.get(tmp.getDotno());
                if (p != null) {
                    if (p.isIslock()) {
                        map.put(tmp.getDotno(), 1);
                    }
                    StationGroupDao obj = new StationGroupDao();
                    obj.setStationname(tmp.getStationname());
                    obj.setDotno(tmp.getDotno());
                    obj.setLasttime(p.getLasttime());
                    obj.setTransnum(tmp.getTransnum());
                    obj.setLeastnum(tmp.getLeastnum());
                    obj.setDleastnum(tmp.getDleastnum());
                    obj.setProcess(tmp.getProcess());
                    obj.setSpecialline(tmp.getSpecialline());
                    re.add(obj);
                }
            }
        }
        if (agvid == 19 || agvid == 20) {
            //发料小车，去掉2，4，6，8锁定的情况
            if (map.containsKey(2)) {
                for (int i = 0; i < re.size(); ) {
                    if (re.get(i).getDotno() == 204 || re.get(i).getDotno() == 206 || re.get(i).getDotno() == 2) {
                        re.remove(i);
                    } else {
                        i++;
                    }
                }
            }
            if (map.containsKey(4)) {
                for (int i = 0; i < re.size(); ) {
                    if (re.get(i).getDotno() == 208 || re.get(i).getDotno() == 210 || re.get(i).getDotno() == 4) {
                        re.remove(i);
                    } else {
                        i++;
                    }
                }
            }
            if (map.containsKey(6)) {
                for (int i = 0; i < re.size(); ) {
                    if (re.get(i).getDotno() == 212 || re.get(i).getDotno() == 214 || re.get(i).getDotno() == 6) {
                        re.remove(i);
                    } else {
                        i++;
                    }
                }
            }
            if (map.containsKey(8)) {
                for (int i = 0; i < re.size(); ) {
                    if (re.get(i).getDotno() == 216 || re.get(i).getDotno() == 218 || re.get(i).getDotno() == 8) {
                        re.remove(i);
                    } else {
                        i++;
                    }
                }
            }
            for (int i = 0; i < re.size(); ) {
                if (re.get(i).getDotno() == 2 || re.get(i).getDotno() == 4
                        || re.get(i).getDotno() == 6 || re.get(i).getDotno() == 8) {
                    re.remove(i);
                } else {
                    i++;
                }
            }


            //再移除已经锁定的点
            for (int i = 0; i < re.size(); ) {
                if (map.containsKey(re.get(i).getDotno())) {
                    re.remove(i);
                } else {
                    i++;
                }
            }
        } else {
            //只要小车上锁了，去掉小车上锁的机台
            if (map.containsKey(204) || map.containsKey(206)) {
                for (int i = 0; i < re.size(); ) {
                    if (re.get(i).getDotno() == 2 || re.get(i).getDotno() == 204 || re.get(i).getDotno() == 206) {
                        re.remove(i);
                    } else {
                        i++;
                    }
                }
            }
            if (map.containsKey(208) || map.containsKey(210)) {
                for (int i = 0; i < re.size(); ) {
                    if (re.get(i).getDotno() == 4 || re.get(i).getDotno() == 208 || re.get(i).getDotno() == 210) {
                        re.remove(i);
                    } else {
                        i++;
                    }
                }
            }
            if (map.containsKey(212) || map.containsKey(214)) {
                for (int i = 0; i < re.size(); ) {
                    if (re.get(i).getDotno() == 6 || re.get(i).getDotno() == 212 || re.get(i).getDotno() == 214) {
                        re.remove(i);
                    } else {
                        i++;
                    }
                }
            }
            if (map.containsKey(216) || map.containsKey(218)) {
                for (int i = 0; i < re.size(); ) {
                    if (re.get(i).getDotno() == 8 || re.get(i).getDotno() == 216 || re.get(i).getDotno() == 218) {
                        re.remove(i);
                    } else {
                        i++;
                    }
                }
            }
            for (int i = 0; i < re.size(); ) {
                if (re.get(i).getDotno() == 204 || re.get(i).getDotno() == 206
                        || re.get(i).getDotno() == 208 || re.get(i).getDotno() == 210
                        || re.get(i).getDotno() == 212 || re.get(i).getDotno() == 214
                        || re.get(i).getDotno() == 216 || re.get(i).getDotno() == 218) {
                    re.remove(i);
                } else {
                    i++;
                }
            }

            //再移除已经锁定的点
            for (int i = 0; i < re.size(); ) {
                if (map.containsKey(re.get(i).getDotno())) {
                    re.remove(i);
                } else {
                    i++;
                }
            }
        }
        return re;
    }

    synchronized List<StationGroupDao> getEmptyListForZRS2(int agvid) {
        List<StationGroupDao> re = new ArrayList<StationGroupDao>();

        List<String> arr = new ArrayList<String>();
        arr.add("2");
        arr.add("4");
        arr.add("6");
        arr.add("8");
        arr.add("204");
        arr.add("206");
        arr.add("208");
        arr.add("210");
        arr.add("212");
        arr.add("214");
        arr.add("216");
        arr.add("218");

        if (agvid == 19 || agvid == 20) {
            //处理小车
            StationLockBean p = lockList.get(2);
            if (p != null && p.isIslock()) {

                arr.remove("204");
                arr.remove("206");
            }
            p = lockList.get(4);
            if (p != null && p.isIslock()) {

                arr.remove("208");
                arr.remove("210");
            }
            p = lockList.get(6);
            if (p != null && p.isIslock()) {

                arr.remove("212");
                arr.remove("214");
            }
            p = lockList.get(8);
            if (p != null && p.isIslock()) {

                arr.remove("216");
                arr.remove("218");
            }

            arr.remove("2");
            arr.remove("4");
            arr.remove("6");
            arr.remove("8");
        } else {
            //大车
            StationLockBean p = lockList.get(204);
            if (p != null && p.isIslock()) {
                arr.remove("2");
            }
            p = lockList.get(206);
            if (p != null && p.isIslock()) {
                arr.remove("2");
            }
            //2号机
            p = lockList.get(208);
            if (p != null && p.isIslock()) {
                arr.remove("4");
            }
            p = lockList.get(210);
            if (p != null && p.isIslock()) {
                arr.remove("4");
            }
            //3号机
            p = lockList.get(212);
            if (p != null && p.isIslock()) {
                arr.remove("6");
            }
            p = lockList.get(214);
            if (p != null && p.isIslock()) {
                arr.remove("6");
            }
            //4号机
            p = lockList.get(216);
            if (p != null && p.isIslock()) {
                arr.remove("8");
            }
            p = lockList.get(218);
            if (p != null && p.isIslock()) {
                arr.remove("8");
            }

            arr.remove("204");
            arr.remove("206");
            arr.remove("208");
            arr.remove("210");
            arr.remove("212");
            arr.remove("214");
            arr.remove("216");
            arr.remove("218");
        }


        if (arr.size() == 0) {
            return re;
        }
        for (int i = 0; i < arr.size(); i++) {
            int px = Integer.parseInt(arr.get(i));
            StationDao tmp = stationList.get(px);
            if (tmp.isIsdisable()) {
                continue;
            }
            StationLockBean p = lockList.get(tmp.getDotno());
            if (p != null && p.isIslock() == false) {
                StationGroupDao obj = new StationGroupDao();
                obj.setStationname(tmp.getStationname());
                obj.setDotno(tmp.getDotno());
                obj.setLasttime(p.getLasttime());
                obj.setTransnum(tmp.getTransnum());
                obj.setLeastnum(tmp.getLeastnum());
                obj.setDleastnum(tmp.getDleastnum());
                obj.setProcess(tmp.getProcess());
                obj.setSpecialline(tmp.getSpecialline());
                re.add(obj);
            }
        }
        return re;
    }

    synchronized List<StationGroupDao> getEmptyListNoSpecialLine(int dotno, List<String> processlist, int agvid) {
        List<StationGroupDao> re = new ArrayList<StationGroupDao>();
        StationBlackBean black = blackList.get(dotno);
        for (Entry<Integer, StationDao> entry : stationList.entrySet()) {
            StationDao tmp = entry.getValue();
            if (processlist.contains(tmp.getProcess()) == false) {
                continue;
            }


            if (tmp.isIsdisable()) {
                continue;
            }

            if (teamUtils.canUse(tmp.getDotno(), agvid) == false) {
                continue;
            }

            // 不能分配的过滤掉
            if (black != null && black.inList(tmp.getDotno())) {
                continue;
            }


            StationLockBean p = lockList.get(tmp.getDotno());
            if (p != null && (p.isIslock() == false || p.getAgvid() == agvid)) {
                StationGroupDao obj = new StationGroupDao();
                obj.setStationname(tmp.getStationname());
                obj.setDotno(tmp.getDotno());
                obj.setLasttime(p.getLasttime());
                obj.setTransnum(tmp.getTransnum());
                obj.setLeastnum(tmp.getLeastnum());
                obj.setDleastnum(tmp.getDleastnum());
                obj.setProcess(tmp.getProcess());
                obj.setSpecialline(tmp.getSpecialline());
                re.add(obj);
            }

        }
        return re;
    }

    /**
     * 找出某工序某线别（含混线的）的可用的机台
     *
     * @param processgroup
     * @param specialline
     * @return
     */
    synchronized List<StationGroupDao> getEmptyList(int dotno, String process, int specialline, int agvid) {
        List<StationGroupDao> re = new ArrayList<StationGroupDao>();
        StationBlackBean black = blackList.get(dotno); // 注意，这个变量不可修改
        for (Entry<Integer, StationDao> entry : stationList.entrySet()) {
            StationDao tmp = entry.getValue();
            if (tmp.getProcess().equals(process) == false) {
                continue;
            }

            if (tmp.isIsdisable()) {
                continue;
            }

            // 分组的过滤掉
            if (teamUtils.canUse(tmp.getDotno(), agvid) == false) {
                continue;
            }
            // 不能分配的过滤掉
            if (black != null && black.inList(tmp.getDotno())) {
                continue;
            }


            if (tmp.getSpecialline() == specialline || tmp.getSpecialline() == -1) {
                StationLockBean p = lockList.get(tmp.getDotno());

                if (p != null && (p.isIslock() == false || p.getAgvid() == agvid)) {
                    StationGroupDao obj = new StationGroupDao();
                    obj.setStationname(tmp.getStationname());
                    obj.setDotno(tmp.getDotno());
                    obj.setLasttime(p.getLasttime());
                    obj.setTransnum(tmp.getTransnum());
                    obj.setLeastnum(tmp.getLeastnum());
                    obj.setDleastnum(tmp.getDleastnum());
                    obj.setProcess(tmp.getProcess());
                    obj.setSpecialline(tmp.getSpecialline());
                    re.add(obj);

                }

            }
        }
        return re;
    }

    StationBean transDaoToBean(StationDao dao) {
        StationBean bean = new StationBean();
        bean.setCmdSign(dao.getCmdSign());
        bean.setStationname(dao.getStationname());
        bean.setSpecialline(dao.getSpecialline());
        bean.setDotno(dao.getDotno());
        bean.setIp(dao.getIp());
        bean.setPort(dao.getPort());
        bean.setLeastnum(dao.getLeastnum());
        bean.setDleastnum(dao.getDleastnum());
        bean.setLine(dao.getLine());
        bean.setTransnum(dao.getTransnum());
        bean.setProcess(dao.getProcess());
        bean.setIsout(dao.isIsout());

        if (dao.getTransType() == 1) {
            bean.setUpTrans(true);
            bean.setDownTrans(false);
        } else if (dao.getTransType() == 2) {
            bean.setUpTrans(false);
            bean.setDownTrans(true);
        } else {
            bean.setUpTrans(true);
            bean.setDownTrans(true);
        }
        bean.setDisable(dao.isIsdisable());
        bean.setFillType(TransDirectionEnum.getTransDirectionEnum(dao.getFilltype()));
        return bean;
    }

    void saveToRedis(StationLockBean obj) {

        new Thread() {

            @Override
            public void run() {
                String key = "stationlocklist";
                String json = gson.toJson(obj);

                Jedis jd = jedisPool.getResource();
                jd.hset(key, "" + obj.getDotno(), json);
                jd.close();

            }
        }.start();

    }

    @Override
    public synchronized void updatePopaidDirection(int dotno, boolean directionOut) {

        StationDao tmp = stationList.get(dotno);
        if (tmp != null) {
            if (directionOut) {
                tmp.setProcess("POPAID下料");
            } else {
                tmp.setProcess("POPAID上料");
            }
        }

    }


    @Override
    public boolean hasEmpty(String process) {
        for (Entry<Integer, StationLockBean> entry : lockList.entrySet()) {
            StationLockBean dao = entry.getValue();
            if (dao.getProcess().equals(process) && dao.isIslock() == false) {
                StationDao tmp = stationList.get(dao.getDotno());
                if (tmp != null && tmp.isIsdisable() == false) {
                    return true;
                }
            }

        }
        return false;
    }

    @Override
    public boolean hasEmpty(List<String> processList) {
        for (Entry<Integer, StationDao> entry : stationList.entrySet()) {
            StationDao station = entry.getValue();
            //机台没有被禁，并且机台工序在列表中
            if (station.isIsdisable() == false && processList.contains(station.getProcess())) {
                StationLockBean dao = lockList.get(entry.getKey());
                //没有上锁的记录或者没有被锁
                if (dao == null || dao.isIslock() == false) {
                    return true;
                }

            }
        }
        return false;

		/*
		for (Entry<Integer, StationLockBean> entry : lockList.entrySet()) {
			StationLockBean dao = entry.getValue();
			if (processList.contains(dao.getProcess())   && dao.isIslock() == false) {
				StationDao tmp = stationList.get(dao.getDotno());
				if (tmp != null&&tmp.isIsdisable()==false) {
					return true;
				}
			}
		}
		return false;
		*/
    }

    @Override
    public void updateStationState(int dotno, boolean disable) {
        StationDao tmp = stationList.get(dotno);
        if (tmp != null) {
            if (tmp.isIsdisable() != disable) {
                // 不相同才修改
                tmp.setIsdisable(disable);
                stationMapper.updateDisable(dotno, disable ? 1 : 0);
            }
        }

    }

    @Override
    public void resetStation(int dotno) {
        StationBean station = getBeanByDot(dotno);
        if (station != null) {
            IStationProtocol stationEvent = StationFactory.getStation(station.getCmdSign());
            byte[] cmd = stationEvent.agvLeave(station.getLine(), station.getFillType());
            if (station.getCmdSign().equals("HC")) {
                sendTools.sendHCData(station.getIp(), station.getPort(), station.getLine(), "AGV已离开", cmd,
                        station.getStationname());
            } else {
                sendTools.sendStationData(station.getIp(), station.getPort(), station.getLine(), "AGV已离开", cmd,
                        station.getStationname());
            }

        }
    }


    /**
     * 查找缓存机，如果有，上锁的同时通知缓存机准备
     */
    @Override
    public synchronized boolean findCache(CacheStationEnumType type, int agvid, boolean toIn, boolean islock) {
        int dotno = type.getDotno();
        StationDao station = stationList.get(dotno);
        if (station == null || station.isIsdisable()) {
            //机台找不到或者被禁用，不满足
            return false;
        }
        if (toIn && station.isIsout()) {
            // 需要上料但是机台是出料模式，不满足
            return false;
        }
        if (toIn == false && station.isIsout() == false) {
            // 需要出料但是机台是上料模式，不满足
            return false;
        }

        StationLockBean dao = lockList.get(dotno);
        if (dao == null || (dao.isIslock() && dao.getAgvid() != agvid)) {
            // 没找到或者被其它agv锁了，不满足
            return false;
        }

        StationMountBean dmount = stationMount.getBean(dotno);
        if (toIn) {
            // 给缓存机上料
            if (dmount.getOutNum() >= station.getTransnum()) {
                // 数量满了
                return false;
            } else {
                // 上锁
                if (islock) {
                    dao.setAgvid(agvid);
                    dao.setIslock(true);
                    dao.setLasttime(System.currentTimeMillis());


                    IStationProtocol stationEvent = StationFactory.getStation(station.getCmdSign());
                    byte[] cmd = stationEvent.agvArrived(station.getLine(), TransDirectionEnum.OnlyIn);
                    HCQueue.Push(station.getIp(), station.getPort(), cmd, "缓存机准备", station.getStationname());

                    saveToRedis(dao);
                }
                return true;
            }
        } else {
            // 拿缓存机的料
            if (dmount.getOutNum() <= 0) {
                // 无料可出
                return false;
            } else {
                // 上锁
                if (islock) {
                    dao.setAgvid(agvid);
                    dao.setIslock(true);
                    dao.setLasttime(System.currentTimeMillis());

                    IStationProtocol stationEvent = StationFactory.getStation(station.getCmdSign());
                    byte[] cmd = stationEvent.agvArrived(station.getLine(), TransDirectionEnum.OnlyOut);
                    HCQueue.Push(station.getIp(), station.getPort(), cmd, "缓存机准备", station.getStationname());

                    saveToRedis(dao);
                }
                return true;
            }
        }

    }

    @Override
    public void turnStation(int dotno) {
        StationDao bean = stationList.get(dotno);
        if (bean != null) {
            if (bean.isIsout()) {
                //设置为false
                bean.setIsout(false);
                stationMapper.updateOut(dotno, 0);
            } else {
                //设置为true
                bean.setIsout(true);
                stationMapper.updateOut(dotno, 1);
            }
        }
    }


    @Override
    public boolean stationCanUse(int dotno, int agvid) {
        StationDao sb = stationList.get(dotno);
        if (sb == null || sb.isIsdisable()) {
            return false;
        }

        StationLockBean dao = lockList.get(dotno);
        if (dao != null) {
            if (dao.isIslock() == false || dao.getAgvid() == agvid) {
                return true;
            }
        }
        return false;
    }

    @Override
    public boolean stationNotDisable(int dotno) {
        StationDao sb = stationList.get(dotno);
        if (sb != null && sb.isIsdisable() == false) {
            return true;
        } else {
            return false;
        }
    }

    @Override
    public synchronized StationGroupDao fetchNextOutStation(int dotno, int agvid, String process, boolean islock) {
        StationLockBean lockstation = null;
        for (Entry<Integer, StationLockBean> entry : lockList.entrySet()) {
            StationLockBean p = entry.getValue();
            if (p.getProcess().equals(process) && p.getAgvid() == agvid) {
                lockstation = p;
                break;
            }
        }
        //已经存在的机台
        if (lockstation != null) {
            StationDao tmp = stationList.get(lockstation.getDotno());
            if (tmp != null && tmp.isIsdisable() == false) {
                StationGroupDao obj = new StationGroupDao();
                obj.setStationname(tmp.getStationname());
                obj.setDotno(tmp.getDotno());
                obj.setProcess(tmp.getProcess());
                obj.setSpecialline(tmp.getSpecialline());
                return obj;
            }
        }
        //处理不存在的
        List<StationGroupDao> list = getEmptyListNoSpecialLine(dotno, process, agvid);
        if (list == null || list.size() == 0) {
            return null;
        }
        List<StationGroupDao> tmp = new ArrayList<StationGroupDao>();
        for (StationGroupDao item : list) {
            StationMountBean bean = stationMount.getBean(item.getDotno());
            if (bean == null) {
                continue;
            }
            item.setNum(bean.getOutNum());
            item.setNum2(10 - bean.getInNum());
            if (bean.getOutNum() >= 2) {
                tmp.add(item);
            }
        }
        if (tmp.size() > 0) {
            // 排序，取第一个
            if (tmp.size() > 1) {
                Collections.sort(tmp, new Comparator<StationGroupDao>() {
                    @Override
                    public int compare(StationGroupDao o1, StationGroupDao o2) {
                        // o1-o2是升序
                        if (o1.getNum() == o2.getNum()) {
                            if (o1.getNum2() == o2.getNum2()) {
                                return (int) (o1.getLasttime() - o2.getLasttime());
                            } else {
                                return o2.getNum2() - o1.getNum2();
                            }
                        } else {
                            return o2.getNum() - o1.getNum();
                        }
                    }
                });
            }
            StationGroupDao first = tmp.get(0);
            if (islock) {
                // 锁机台
                StationLockBean dao = lockList.get(first.getDotno());

                if (dao != null) {
                    // 强制锁
                    dao.setAgvid(agvid);
                    dao.setIslock(true);
                    dao.setLasttime(System.currentTimeMillis());

                    teamUtils.setLock(first.getDotno(), true);

                    saveToRedis(dao);
                }
            }
            return first;
        }
        return null;
    }

    @Override
    public synchronized StationGroupDao fetchNextInStation(int dotno, int agvid, String process, int specialLine, boolean islock) {
        StationLockBean lockstation = null;
        for (Entry<Integer, StationLockBean> entry : lockList.entrySet()) {
            StationLockBean p = entry.getValue();
            if (p.getProcess().equals(process) && p.getAgvid() == agvid) {
                lockstation = p;
                break;
            }
        }
        //已经存在的机台
        if (lockstation != null) {
            StationDao tmp = stationList.get(lockstation.getDotno());
            if (tmp != null && tmp.isIsdisable() == false) {
                StationGroupDao obj = new StationGroupDao();
                obj.setStationname(tmp.getStationname());
                obj.setDotno(tmp.getDotno());
                obj.setProcess(tmp.getProcess());
                obj.setSpecialline(tmp.getSpecialline());
                return obj;
            }
        }
        //处理不存在的
        List<StationGroupDao> list;
        if (process.equals("制绒上料") || process.equals("发料上料")) {
            list = getEmptyListForZRS2(agvid);
            //list = getEmptyList(dotno, process,specialLine, agvid);
        } else {
            list = getEmptyList(dotno, process, specialLine, agvid);
        }
        if (list == null || list.size() == 0) {
            return null;
        }
        List<StationGroupDao> tmp = new ArrayList<StationGroupDao>();
        for (StationGroupDao item : list) {
            StationMountBean bean = stationMount.getBean(item.getDotno());
            if (bean == null) {
                continue;
            }
            item.setNum(10 - bean.getInNum());
            item.setNum2(bean.getOutNum());
            tmp.add(item);
        }
        if (tmp.size() > 0) {
            // 排序，取第一个
            if (tmp.size() > 1) {
                Collections.sort(tmp, new Comparator<StationGroupDao>() {
                    @Override
                    public int compare(StationGroupDao o1, StationGroupDao o2) {
                        // o1-o2是升序
                        if (o1.getNum() == o2.getNum()) {
                            if (o1.getNum2() == o2.getNum2()) {
                                return (int) (o1.getLasttime() - o2.getLasttime());
                            } else {
                                return o2.getNum2() - o1.getNum2();
                            }
                        } else {
                            return o2.getNum() - o1.getNum();
                        }
                    }
                });
            }
            StationGroupDao first = tmp.get(0);
            if (islock) {
                // 锁机台
                StationLockBean dao = lockList.get(first.getDotno());
                if (dao != null) {
                    // 强制锁
                    dao.setAgvid(agvid);
                    dao.setIslock(true);
                    dao.setLasttime(System.currentTimeMillis());


                    teamUtils.setLock(first.getDotno(), true);


                    saveToRedis(dao);
                }
            }
            return first;
        }
        return null;
    }

    @Override
    public synchronized StationGroupDao fetchNextOutStation(int dotno, int agvid, List<String> processlist, boolean islock) {
        StationLockBean lockstation = null;
        for (Entry<Integer, StationLockBean> entry : lockList.entrySet()) {
            StationLockBean p = entry.getValue();
            if (processlist.contains(p.getProcess()) && p.getAgvid() == agvid) {
                lockstation = p;
                break;
            }
        }
        //已经存在的机台
        if (lockstation != null) {
            StationDao tmp = stationList.get(lockstation.getDotno());
            if (tmp != null && tmp.isIsdisable() == false) {
                StationGroupDao obj = new StationGroupDao();
                obj.setStationname(tmp.getStationname());
                obj.setDotno(tmp.getDotno());
                obj.setProcess(tmp.getProcess());
                obj.setSpecialline(tmp.getSpecialline());
                return obj;
            }
        }
        //处理不存在的
        List<StationGroupDao> list = getEmptyListNoSpecialLine(dotno, processlist, agvid);
        if (list == null || list.size() == 0) {
            return null;
        }
        List<StationGroupDao> tmp = new ArrayList<StationGroupDao>();
        for (StationGroupDao item : list) {
            StationMountBean bean = stationMount.getBean(item.getDotno());
            if (bean == null) {
                continue;
            }
            item.setNum(bean.getOutNum());
            item.setNum2(10 - bean.getInNum());
            if (bean.getOutNum() >= 2) {
                tmp.add(item);
            }
        }
        if (tmp.size() > 0) {
            // 排序，取第一个
            if (tmp.size() > 1) {
                Collections.sort(tmp, new Comparator<StationGroupDao>() {
                    @Override
                    public int compare(StationGroupDao o1, StationGroupDao o2) {
                        // o1-o2是升序
                        if (o1.getNum() == o2.getNum()) {
                            if (o1.getNum2() == o2.getNum2()) {
                                return (int) (o1.getLasttime() - o2.getLasttime());
                            } else {
                                return o2.getNum2() - o1.getNum2();
                            }
                        } else {
                            return o2.getNum() - o1.getNum();
                        }
                    }
                });
            }
            StationGroupDao first = tmp.get(0);
            if (islock) {
                // 锁机台
                StationLockBean dao = lockList.get(first.getDotno());

                if (dao != null) {
                    // 强制锁
                    dao.setAgvid(agvid);
                    dao.setIslock(true);
                    dao.setLasttime(System.currentTimeMillis());

                    teamUtils.setLock(first.getDotno(), true);
                    saveToRedis(dao);
                }
            }
            return first;
        }
        return null;
    }

    @Override
    public synchronized void unlockStationForAgv(int agvid, int exceptionDot) {
        for (Entry<Integer, StationLockBean> entry : lockList.entrySet()) {
            if (entry.getKey() != exceptionDot) {
                //解锁其它点位
                StationLockBean bean = entry.getValue();
                if (bean.getAgvid() == agvid) {
                    //解锁该机台
                    bean.setAgvid(0);
                    bean.setIslock(false);

                    teamUtils.setLock(entry.getKey(), false);

                    saveToRedis(bean);
                }
            }
        }
    }

    @Override
    public void lockStationOnTarget(int dotno, int agvId) {
        for (Entry<Integer, StationLockBean> entry : lockList.entrySet()) {
            StationLockBean bean = entry.getValue();
            if (entry.getKey() == dotno) {
                //当前位置
                if (bean.getAgvid() != agvId) {
                    bean.setAgvid(agvId);
                    bean.setIslock(true);
                    bean.setLasttime(System.currentTimeMillis());
                    saveToRedis(bean);

                    teamUtils.setLock(entry.getKey(), true);
                } else {
                    //相同的不处理
                }
            } else {
                //其它点位
                if (bean.getAgvid() == agvId) {
                    bean.setAgvid(0);
                    bean.setIslock(false);

                    teamUtils.setLock(entry.getKey(), false);
                    saveToRedis(bean);
                }
            }
        }
    }

    @Override
    public StationGroupDao fetchNextOutStationForDot(int dotno, int agvid, List<Integer> stationDots, boolean islock) {
        StationLockBean lockstation = null;
        for (Entry<Integer, StationLockBean> entry : lockList.entrySet()) {
            StationLockBean p = entry.getValue();
            if (stationDots.contains(p.getDotno()) && p.getAgvid() == agvid) {
                lockstation = p;
                break;
            }
        }
        //已经存在的机台
        if (lockstation != null) {
            StationDao tmp = stationList.get(lockstation.getDotno());
            if (tmp != null && tmp.isIsdisable() == false) {
                StationGroupDao obj = new StationGroupDao();
                obj.setStationname(tmp.getStationname());
                obj.setDotno(tmp.getDotno());
                obj.setProcess(tmp.getProcess());
                obj.setSpecialline(tmp.getSpecialline());
                return obj;
            }
        }
        //处理不存在的
        List<StationGroupDao> list = getEmptyListNoSpecialLineDot(dotno, stationDots, agvid);
        if (list == null || list.size() == 0) {
            return null;
        }
        List<StationGroupDao> tmp = new ArrayList<StationGroupDao>();
        for (StationGroupDao item : list) {
            StationMountBean bean = stationMount.getBean(item.getDotno());
            if (bean == null) {
                continue;
            }
            item.setNum(bean.getOutNum());
            item.setNum2(10 - bean.getInNum());
            if (bean.getOutNum() >= 2) {
                tmp.add(item);
            }
        }
        if (tmp.size() > 0) {
            // 排序，取第一个
            if (tmp.size() > 1) {
                Collections.sort(tmp, new Comparator<StationGroupDao>() {
                    @Override
                    public int compare(StationGroupDao o1, StationGroupDao o2) {
                        // o1-o2是升序
                        if (o1.getNum() == o2.getNum()) {
                            if (o1.getNum2() == o2.getNum2()) {
                                return (int) (o1.getLasttime() - o2.getLasttime());
                            } else {
                                return o2.getNum2() - o1.getNum2();
                            }
                        } else {
                            return o2.getNum() - o1.getNum();
                        }
                    }
                });
            }
            StationGroupDao first = tmp.get(0);
            if (islock) {
                // 锁机台
                StationLockBean dao = lockList.get(first.getDotno());

                if (dao != null) {
                    // 强制锁
                    dao.setAgvid(agvid);
                    dao.setIslock(true);
                    dao.setLasttime(System.currentTimeMillis());

                    teamUtils.setLock(first.getDotno(), true);

                    saveToRedis(dao);
                }
            }
            return first;
        }
        return null;
    }

    @Override
    public StationGroupDao fetchNextBSGOutStation(int dotno, int agvid, String process, int number) {
        StationLockBean lockstation = null;
        for (Entry<Integer, StationLockBean> entry : lockList.entrySet()) {
            StationLockBean p = entry.getValue();
            if (p.getProcess().equals(process) && p.getAgvid() == agvid) {
                lockstation = p;
                break;
            }
        }
        //已经存在的机台
        if (lockstation != null) {
            StationDao tmp = stationList.get(lockstation.getDotno());
            if (tmp != null && tmp.isIsdisable() == false) {
                StationGroupDao obj = new StationGroupDao();
                obj.setStationname(tmp.getStationname());
                obj.setDotno(tmp.getDotno());
                obj.setProcess(tmp.getProcess());
                obj.setSpecialline(tmp.getSpecialline());
                return obj;
            }
        }
        //处理不存在的
        List<StationGroupDao> list = getEmptyListNoSpecialLine(dotno, process, agvid);
        if (list == null || list.size() == 0) {
            return null;
        }
        List<StationGroupDao> tmp = new ArrayList<StationGroupDao>();
        for (StationGroupDao item : list) {
            StationMountBean bean = stationMount.getBean(item.getDotno());
            if (bean == null) {
                continue;
            }
            item.setNum(bean.getOutNum());
            item.setNum2(10 - bean.getInNum());
            if (bean.getOutNum() >= number) {
                tmp.add(item);
            }
        }
        if (tmp.size() > 0) {
            // 排序，取第一个
            if (tmp.size() > 1) {
                Collections.sort(tmp, new Comparator<StationGroupDao>() {
                    @Override
                    public int compare(StationGroupDao o1, StationGroupDao o2) {
                        // o1-o2是升序
                        if (o1.getNum() == o2.getNum()) {
                            if (o1.getNum2() == o2.getNum2()) {
                                return (int) (o1.getLasttime() - o2.getLasttime());
                            } else {
                                return o2.getNum2() - o1.getNum2();
                            }
                        } else {
                            return o2.getNum() - o1.getNum();
                        }
                    }
                });
            }
            StationGroupDao first = tmp.get(0);
            // 锁机台
            StationLockBean dao = lockList.get(first.getDotno());

            if (dao != null) {
                // 强制锁
                dao.setAgvid(agvid);
                dao.setIslock(true);
                dao.setLasttime(System.currentTimeMillis());

                teamUtils.setLock(first.getDotno(), true);

                saveToRedis(dao);
            }

            return first;
        }
        return null;
    }

}
